<template>
  <span>
    <a-upload
      accept=".xlsx, .xls"
      @change="readFile"
      :showUploadList="false"
      :customRequest="() => {}">
      <a-button type="primary">{{ btnTitle }}</a-button>
    </a-upload>

    <a-modal :title="title" centered :visible="state.visible" :footer="null" @cancel="handleClose">
      <a-row
        :gutter="[16, 16]"
        :style="{
          'margin-top': title === '' ? '30px' : '0'
        }">
        <a-col>
          <a-steps :current="state.currentStep">
            <a-step v-for="(item, index) in this.steps" :key="index" :title="item.title">
              <a-icon slot="icon" v-if="index === state.currentStep" type="loading"/>
            </a-step>
          </a-steps>
        </a-col>
        <!--读取文件时不加载进度条等-->
        <a-col v-if="state.currentStep !== 0">
          <a-progress :percent="state.currentProcessingProgress" status="active"/>
        </a-col>
        <a-col v-if="state.currentStep !== 0" style="height: 30%; overflow: scroll;">
          <a-timeline>
            <a-timeline-item v-for="(item, index) in state.processingProgressTimeline" :key="index" :color="item.color">
              <p v-for="(content, index) in item.content" :key="index">{{ content }}</p>
            </a-timeline-item>
          </a-timeline>
        </a-col>
      </a-row>
    </a-modal>
  </span>
</template>

<script>
  import XLSX from 'xlsx'

  export default {
    name: 'ProgressTimeLine',
    props: {
      title: {
        type: String,
        default: ''
      },
      steps: {
        type: Array,
        default: () => [],
        required: true
      },
      handleBefore: {
        type: Function,
        default: () => {}
      },
      handleRaw: {
        type: Function,
        default: (item, list) => new Promise(resolve => resolve())
      },
      btnTitle: {
        type: String,
        default: '',
        required: true
      },
      sendingInterval: {
        type: Number,
        default: 100
      }
    },
    data () {
      return {
        state: {
          visible: false,
          currentStep: 0,
          currentProcessingProgress: 0,
          processingProgressTimeline: []
        }
      }
    },
    methods: {
      async readFile (e) {
        const { state } = this

        await this.handleBefore()
        this.state.visible = true
        this.readXlsFile(e.file.originFileObj, result => {
          // 第一步 读取文件
          state.currentStep++

          // 第二步 处理
          const totalProcess = result.length
          let currentProcess = 0
          if (result.length > 0) {
            const processHandler = setInterval(_ => {
              const item = result.shift()
              this.handleRaw(item, state.processingProgressTimeline)
                .finally(_ => {
                  currentProcess++
                  state.currentProcessingProgress = (currentProcess / totalProcess) * 100
                })

              if (result.length <= 0) {
                clearInterval(processHandler)
              }
            }, this.sendingInterval)
          }

          // 第三步 完成
          state.currentStep++
          state.currentStep++ // 再加一下让 currentStep 不在完成上,以便最后一项"完成"
        })
      },
      readXlsFile (file, callback) {
        const fileReader = new FileReader()

        fileReader.onload = event => {
          try {
            const data = event.target.result
            const workbook = XLSX.read(data, {
              type: 'binary'
            })
            const wsname = workbook.SheetNames[0] // 取第一张表
            const ws = XLSX.utils.sheet_to_json(workbook.Sheets[wsname]) // 生成json表格内容

            callback(ws)
          } catch (e) {
            console.error(e)
          }
        }
        fileReader.readAsBinaryString(file)
      },
      handleClose () {
        // 用下面的方式中断剩余请求,简单粗暴
        window.location.reload()

        // 优雅点的, 差中断剩余请求
        // this.state = {
        //   visible: false,
        //   currentStep: 0,
        //   currentProcessingProgress: 0,
        //   processingProgressTimeline: []
        // }
        //
        // this.$emit('close')
      }
    }
  }
</script>

<style scoped>

</style>
